Waits with Java in Selenium
Waits are one of the most important concepts in Selenium automation. Modern web applications often load elements asynchronously, update content dynamically, display animations, open popups, or make elements available only after a particular condition is satisfied. Selenium waits help synchronize the automation script with the actual state of the web application.
Without proper synchronization, Selenium may try to interact with an element before it is available, visible, enabled, or clickable. This can result in exceptions such as NoSuchElementException, ElementNotInteractableException, ElementClickInterceptedException, and TimeoutException.
In Selenium Java, the main waiting approaches are Implicit Wait, Explicit Wait, and Fluent Wait. Selenium's Java API provides WebDriverWait as a specialization of FluentWait, while ExpectedConditions provides commonly used conditions for explicit waits. :contentReference[oaicite:0]{index=0}
Course Resource: Selenium Training | Register for Course Demo
1. What is a Wait in Selenium?
A Wait tells Selenium to pause or repeatedly check for a specific condition before continuing with the next operation.
For example, suppose a login button appears only after a page finishes loading. If Selenium immediately executes click(), the element may not yet be ready. Instead, Selenium can wait until the button becomes clickable and then perform the click.
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement loginButton =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("login")
)
);
loginButton.click();
Explicit waits repeatedly evaluate a condition until it succeeds or the timeout is reached. Selenium's Java API represents these conditions through ExpectedCondition and provides ready-to-use conditions through ExpectedConditions. :contentReference[oaicite:1]{index=1}
2. Why are Waits Important?
Real-world web applications rarely behave like static HTML pages. Elements may appear after JavaScript execution, AJAX requests, API responses, animations, page transitions, or other asynchronous operations.
Waits help Selenium synchronize the test with these changing application states.
- Wait for elements to appear.
- Wait for elements to become visible.
- Wait for elements to become clickable.
- Wait for elements to become enabled.
- Wait for text to appear.
- Wait for a page title.
- Wait for a URL to change.
- Wait for an alert.
- Wait for an iframe to become available.
- Wait for an element to disappear.
- Wait for a DOM element to become stale.
- Synchronize automation with AJAX and JavaScript operations.
3. Basic Wait Flow
Start Test
|
v
Open Browser
|
v
Open Web Application
|
v
Locate Element
|
v
Is Required Condition Satisfied?
|
+---- No ----> Keep Waiting
|
Yes
|
v
Perform Operation
|
v
Validate Result
|
v
Continue Test
4. Types of Waits in Selenium
| Wait Type | Description | Typical Usage |
| Implicit Wait | Applies a default wait when locating elements | General element lookup synchronization |
| Explicit Wait | Waits for a specific condition | Dynamic elements and specific states |
| Fluent Wait | Configurable wait with timeout, polling interval, and ignored exceptions | Advanced synchronization requirements |
| Thread.sleep() | Pauses execution for a fixed amount of time | Generally discouraged for normal synchronization |
5. Implicit Wait
An Implicit Wait tells WebDriver to wait for a specified amount of time when trying to find elements if they are not immediately available.
import java.time.Duration;
driver.manage().timeouts().implicitlyWait(
Duration.ofSeconds(10)
);
After this setting, element lookup operations can wait up to the configured duration before failing to find an element.
Example
driver.manage().timeouts().implicitlyWait(
Duration.ofSeconds(10)
);
WebElement username =
driver.findElement(By.id("username"));
username.sendKeys("admin");
6. Characteristics of Implicit Wait
- It is configured on the WebDriver.
- It applies broadly to element lookup operations.
- It does not describe a specific application condition.
- It can make simple scripts more tolerant of delayed element availability.
- It should be configured deliberately as part of the synchronization strategy.
7. Advantages of Implicit Wait
- Simple to configure.
- Applies globally to WebDriver element lookup.
- Reduces failures caused by very small delays in locating elements.
- Requires less repeated wait code for basic lookup scenarios.
8. Disadvantages of Implicit Wait
- It is not designed for detailed condition-based synchronization.
- It does not directly express conditions such as clickable, visible, title contains, or alert present.
- Large timeout values can make failures slower to diagnose.
- Combining implicit and explicit waits can make timing behavior harder to reason about.
9. Explicit Wait
An Explicit Wait waits for a particular condition before continuing. It is especially useful for dynamic web applications.
Selenium's Java WebDriverWait is commonly used for explicit waits. It extends FluentWait<WebDriver> and uses a timeout specified with Duration. :contentReference[oaicite:2]{index=2}
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement username =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
username.sendKeys("admin");
10. Basic Explicit Wait Syntax
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
ExpectedConditions.condition(...)
);
The general process is:
- Create a WebDriverWait object.
- Specify the maximum timeout.
- Define the expected condition.
- Call until().
- Continue when the condition is satisfied.
11. WebDriverWait
WebDriverWait is the Selenium Java class commonly used for explicit waits. It is a specialization of FluentWait for WebDriver instances. :contentReference[oaicite:3]{index=3}
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
The timeout determines how long Selenium can wait for the condition before a timeout failure occurs.
12. ExpectedConditions
ExpectedConditions provides commonly used predefined conditions for WebDriver tests. Examples include waiting for an element to be present, visible, clickable, an alert to appear, a URL to match, a title to match, an element to become stale, and more. :contentReference[oaicite:4]{index=4}
| Condition | Purpose |
| presenceOfElementLocated() | Waits for an element to exist in the DOM |
| visibilityOfElementLocated() | Waits for an element to be present and visible |
| elementToBeClickable() | Waits for an element to be visible and enabled for clicking |
| textToBePresentInElement() | Waits for specific text in an element |
| titleIs() | Waits for an exact page title |
| titleContains() | Waits for part of a page title |
| urlToBe() | Waits for an exact URL |
| urlContains() | Waits for part of a URL |
| alertIsPresent() | Waits for an alert |
| invisibilityOfElementLocated() | Waits for an element to become invisible or absent |
| stalenessOf() | Waits for an element to become detached from the DOM |
| frameToBeAvailableAndSwitchToIt() | Waits for a frame and switches into it |
| numberOfElementsToBe() | Waits for a specific number of matching elements |
13. presenceOfElementLocated()
The presenceOfElementLocated() condition waits until an element is present in the DOM.
WebElement username =
wait.until(
ExpectedConditions.presenceOfElementLocated(
By.id("username")
)
);
Presence does not necessarily mean that the element is visible or ready for user interaction. It means Selenium can locate the element in the DOM.
14. visibilityOfElementLocated()
The visibilityOfElementLocated() condition waits until the element is present and visible.
WebElement username =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
username.sendKeys("admin");
This is useful when an element exists in the DOM but may initially be hidden.
15. elementToBeClickable()
The elementToBeClickable() condition waits until an element is visible and enabled so that it can be clicked. :contentReference[oaicite:5]{index=5}
WebElement loginButton =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("login")
)
);
loginButton.click();
16. Waiting for Text
The textToBePresentInElement() condition can be used when a page displays text asynchronously.
wait.until(
ExpectedConditions.textToBePresentInElement(
driver.findElement(By.id("message")),
"Login successful"
)
);
Alternative Locator-Based Example
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("message"),
"Login successful"
)
);
17. Waiting for Page Title
titleIs()
wait.until(
ExpectedConditions.titleIs("Dashboard")
);
titleContains()
wait.until(
ExpectedConditions.titleContains("Dashboard")
);
These conditions are useful when navigation is asynchronous or when the title changes after a page transition. :contentReference[oaicite:6]{index=6}
18. Waiting for URL
urlToBe()
wait.until(
ExpectedConditions.urlToBe(
"https://example.com/dashboard"
)
);
urlContains()
wait.until(
ExpectedConditions.urlContains("dashboard")
);
19. Waiting for an Alert
When an alert is generated by the application, Selenium can wait for the alert to appear.
Alert alert =
wait.until(
ExpectedConditions.alertIsPresent()
);
System.out.println(alert.getText());
alert.accept();
20. Waiting for an Element to Disappear
The invisibilityOfElementLocated() condition waits until an element becomes invisible or is no longer present.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.id("loading")
)
);
This is especially useful for loading spinners, overlays, progress indicators, and temporary messages.
21. Waiting for a Loading Spinner
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(15)
);
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-spinner")
)
);
driver.findElement(
By.id("submit")
).click();
22. Waiting for an Element to Become Stale
The stalenessOf() condition waits until a previously located element is no longer attached to the DOM. :contentReference[oaicite:7]{index=7}
WebElement oldElement =
driver.findElement(By.id("result"));
driver.findElement(By.id("refresh")).click();
wait.until(
ExpectedConditions.stalenessOf(oldElement)
);
23. Waiting for an iframe
If an iframe is loaded dynamically, Selenium can wait for it to become available and switch into it.
wait.until(
ExpectedConditions.frameToBeAvailableAndSwitchToIt(
By.id("paymentFrame")
)
);
driver.findElement(
By.id("cardNumber")
).sendKeys("4111111111111111");
driver.switchTo().defaultContent();
Selenium provides frame-specific expected conditions that can switch the driver into the frame once it is available. :contentReference[oaicite:8]{index=8}
24. Waiting for Multiple Elements
Explicit waits can also be used when a page is expected to display multiple elements.
List<WebElement> products =
wait.until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(
By.cssSelector(".product")
)
);
System.out.println(
"Products: " + products.size()
);
25. Waiting for a Specific Number of Elements
wait.until(
ExpectedConditions.numberOfElementsToBe(
By.cssSelector(".product"),
5
)
);
This can be useful when an application loads a list incrementally and the test expects a particular number of elements before continuing. Selenium's Java API includes conditions for exact, minimum, and maximum element counts. :contentReference[oaicite:9]{index=9}
26. Fluent Wait
FluentWait provides more control over waiting behavior. It allows configuration of the timeout, polling interval, and exceptions that should be ignored while the condition is being evaluated. :contentReference[oaicite:10]{index=10}
FluentWait<WebDriver> wait =
new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(15))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);
27. Fluent Wait Syntax
Wait<WebDriver> wait =
new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(10))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);
wait.until(
driver -> driver.findElement(
By.id("username")
).isDisplayed()
);
28. Polling Interval
The polling interval controls how frequently Selenium checks the waiting condition.
FluentWait<WebDriver> wait =
new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(20))
.pollingEvery(Duration.ofSeconds(1));
For example, a one-second polling interval means the condition is evaluated periodically rather than continuously. FluentWait supports configurable polling behavior. :contentReference[oaicite:11]{index=11}
29. Ignoring Exceptions with FluentWait
FluentWait can be configured to ignore selected exceptions while waiting.
FluentWait<WebDriver> wait =
new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(15))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);
This can be useful when an element is expected to appear during repeated polling.
30. Custom Condition with FluentWait
Wait<WebDriver> wait =
new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(15))
.pollingEvery(Duration.ofMillis(500));
WebElement element =
wait.until(
driver -> {
WebElement field =
driver.findElement(By.id("username"));
return field.isDisplayed()
? field
: null;
}
);
31. Lambda Expression with WebDriverWait
Java allows a custom condition to be expressed using a lambda.
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.until(
driver ->
driver.findElement(
By.id("message")
).isDisplayed()
);
Selenium's wait API accepts a condition that is evaluated until it returns a non-null or non-false result. :contentReference[oaicite:12]{index=12}
32. Custom Text Wait
wait.until(
driver -> {
String text =
driver.findElement(
By.id("message")
).getText();
return text.equals("Success");
}
);
33. Custom Attribute Wait
wait.until(
driver -> {
String value =
driver.findElement(
By.id("status")
).getAttribute("class");
return value != null &&
value.contains("completed");
}
);
34. Wait for Element to Be Enabled
WebElement submitButton =
wait.until(
driver -> {
WebElement button =
driver.findElement(
By.id("submit")
);
return button.isEnabled()
? button
: null;
}
);
submitButton.click();
35. Wait for Element to Be Selected
wait.until(
driver ->
driver.findElement(
By.id("terms")
).isSelected()
);
36. Wait for Element to Be Visible and Enabled
WebElement submit =
wait.until(
driver -> {
WebElement element =
driver.findElement(
By.id("submit")
);
if (element.isDisplayed() &&
element.isEnabled()) {
return element;
}
return null;
}
);
submit.click();
37. Implicit vs Explicit Wait
| Implicit Wait | Explicit Wait |
| Configured on WebDriver | Configured for a particular condition |
| Applies broadly to element lookup | Applied where synchronization is required |
| Simple configuration | More precise control |
| Does not express detailed conditions | Supports visibility, clickability, text, title, URL, alerts, frames, etc. |
| Useful for general lookup delays | Useful for dynamic application states |
38. Explicit Wait vs Fluent Wait
| Explicit Wait | Fluent Wait |
| Usually implemented with WebDriverWait | Implemented with FluentWait |
| Simple condition-based synchronization | Highly configurable synchronization |
| Uses predefined ExpectedConditions or custom conditions | Supports custom conditions and configurable polling |
| Less configuration required | More control over polling and ignored exceptions |
| Suitable for most common dynamic element scenarios | Useful for advanced synchronization requirements |
39. Thread.sleep() in Selenium
Thread.sleep() pauses the Java thread for a fixed amount of time.
Thread.sleep(5000);
This means the program will stop execution for five seconds regardless of whether the element becomes ready after one second or remains unavailable for the entire five seconds.
40. Why Thread.sleep() is Usually Not Preferred
- It always waits the full specified duration.
- It can make tests unnecessarily slow.
- It does not check a meaningful application condition.
- It can still fail if the application takes longer than the fixed delay.
- It makes test synchronization less adaptive.
41. Thread.sleep() vs Explicit Wait
| Thread.sleep() | Explicit Wait |
| Fixed delay | Condition-based wait |
| Always waits the specified duration | Continues as soon as the condition succeeds |
| Not aware of application state | Checks application state |
| Can slow down tests | Usually more efficient for dynamic conditions |
| Less maintainable for synchronization | More expressive and maintainable |
42. Mixing Implicit and Explicit Waits
Care should be taken when combining implicit and explicit waits. Both mechanisms influence synchronization behavior, and mixing them can make timing behavior harder to understand and troubleshoot.
For most framework designs, it is useful to establish a clear synchronization strategy and use explicit waits where specific application conditions need to be verified.
43. Wait for Login Button
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement login =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("loginButton")
)
);
login.click();
44. Wait for Search Results
WebElement results =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".search-results")
)
);
System.out.println(
results.getText()
);
45. Wait for a Success Message
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("message"),
"Login successful"
)
);
46. Wait for Loading Overlay to Disappear
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-overlay")
)
);
47. Wait for URL After Login
loginButton.click();
wait.until(
ExpectedConditions.urlContains("dashboard")
);
48. Wait for Title After Navigation
driver.findElement(
By.linkText("Dashboard")
).click();
wait.until(
ExpectedConditions.titleContains("Dashboard")
);
49. Wait for Dynamic Button
WebElement button =
wait.until(
ExpectedConditions.elementToBeClickable(
By.cssSelector("button.submit")
)
);
button.click();
50. Wait for Dynamic Text
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("status"),
"Completed"
)
);
51. Wait for AJAX Request Result
When an application updates the page after an AJAX request, waiting for a meaningful UI condition is generally more reliable than using a fixed delay.
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".ajax-result")
)
);
52. Wait for a Modal Dialog
WebElement modal =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".modal")
)
);
System.out.println(
"Modal: " + modal.getText()
);
53. Wait for a Checkbox
WebElement checkbox =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("terms")
)
);
if (!checkbox.isSelected()) {
checkbox.click();
}
54. Wait for a Radio Button
WebElement radio =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("male")
)
);
if (!radio.isSelected()) {
radio.click();
}
55. Wait for an Input Field
WebElement username =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
username.clear();
username.sendKeys("admin");
56. Wait for Multiple Products
List<WebElement> products =
wait.until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(
By.cssSelector(".product-card")
)
);
for (WebElement product : products) {
System.out.println(product.getText());
}
57. Wait for an Alert and Accept It
Alert alert =
wait.until(
ExpectedConditions.alertIsPresent()
);
System.out.println(
"Alert: " + alert.getText()
);
alert.accept();
58. Wait for an iframe and Switch to It
wait.until(
ExpectedConditions.frameToBeAvailableAndSwitchToIt(
By.id("paymentFrame")
)
);
WebElement cardNumber =
driver.findElement(By.id("cardNumber"));
cardNumber.sendKeys("4111111111111111");
driver.switchTo().defaultContent();
59. Wait for a Page Element After Refresh
driver.navigate().refresh();
WebElement username =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
username.sendKeys("admin");
60. Handling TimeoutException
If the expected condition is not satisfied within the configured timeout, Selenium can throw a TimeoutException.
try {
WebElement button =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit")
)
);
button.click();
} catch (TimeoutException e) {
System.out.println(
"Element was not ready within the timeout."
);
}
61. Common Causes of TimeoutException
- Incorrect locator.
- Element never appears.
- Element remains hidden.
- Element remains disabled.
- Application response is slower than expected.
- Wrong page or browser window.
- Element is inside an iframe.
- Unexpected popup or overlay blocks the application.
- Incorrect expected condition.
- Application behavior changed.
62. Handling Stale Elements with Waits
Dynamic applications can redraw elements. Selenium provides conditions such as stalenessOf() and refreshed() to help synchronize with DOM changes. :contentReference[oaicite:13]{index=13}
WebElement oldElement =
driver.findElement(By.id("result"));
driver.findElement(By.id("refresh")).click();
wait.until(
ExpectedConditions.stalenessOf(oldElement)
);
WebElement newElement =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("result")
)
);
63. refreshed() Condition
The refreshed() condition can wrap another expected condition when an element may be redrawn during the wait.
WebElement result =
wait.until(
ExpectedConditions.refreshed(
ExpectedConditions.visibilityOfElementLocated(
By.id("result")
)
)
);
64. Logical AND Conditions
Selenium's expected conditions support combining conditions with logical operations such as and().
wait.until(
ExpectedConditions.and(
ExpectedConditions.visibilityOfElementLocated(
By.id("submit")
),
ExpectedConditions.elementToBeClickable(
By.id("submit")
)
)
);
65. Logical OR Conditions
The or() condition can be used when one of several possible conditions is acceptable.
wait.until(
ExpectedConditions.or(
ExpectedConditions.visibilityOfElementLocated(
By.id("success")
),
ExpectedConditions.visibilityOfElementLocated(
By.id("error")
)
)
);
Selenium's Java ExpectedConditions API provides logical and() and or() combinations for expected conditions. :contentReference[oaicite:14]{index=14}
66. Wait Until a Condition Is False
Wait APIs also support waiting until a condition becomes false through until() with an appropriate custom condition or the relevant wait functionality.
wait.until(
driver ->
!driver.findElement(
By.id("loading")
).isDisplayed()
);
67. WebDriverWait with Custom Timeout Message
FluentWait provides methods for configuring timeout behavior and timeout messages. :contentReference[oaicite:15]{index=15}
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
wait.withMessage(
"Login button was not ready"
);
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("login")
)
);
68. Web Element Wait Strategy
Identify Element
|
v
Is Element Present?
|
Yes
|
v
Is Element Visible?
|
Yes
|
v
Is Element Enabled?
|
Yes
|
v
Is Element Clickable?
|
Yes
|
v
Perform Action
69. Choosing the Correct Wait
| Situation | Recommended Approach |
| General element lookup delay | Implicit Wait or targeted explicit synchronization |
| Element must become visible | visibilityOfElementLocated() |
| Element must be clicked | elementToBeClickable() |
| Element must exist in DOM | presenceOfElementLocated() |
| Text must appear | textToBePresentInElementLocated() |
| Loading overlay must disappear | invisibilityOfElementLocated() |
| Page title must change | titleIs() or titleContains() |
| URL must change | urlToBe() or urlContains() |
| Alert must appear | alertIsPresent() |
| Iframe must become available | frameToBeAvailableAndSwitchToIt() |
| DOM element must be replaced | stalenessOf() or refreshed() |
| Custom polling required | FluentWait |
70. Complete Login Example Using Explicit Wait
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoginWithWait {
public static void main(String[] args) {
WebDriver driver =
new ChromeDriver();
try {
driver.manage().window().maximize();
driver.get(
"https://example.com"
);
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement username =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
WebElement password =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("password")
)
);
username.clear();
username.sendKeys("admin");
password.clear();
password.sendKeys("Password123");
WebElement loginButton =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("login")
)
);
loginButton.click();
wait.until(
ExpectedConditions.urlContains(
"dashboard"
)
);
} finally {
driver.quit();
}
}
}
71. Complete Fluent Wait Example
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
public class FluentWaitExample {
public static void main(String[] args) {
WebDriver driver =
new ChromeDriver();
try {
driver.get(
"https://example.com"
);
FluentWait<WebDriver> wait =
new FluentWait<>(driver)
.withTimeout(
Duration.ofSeconds(15)
)
.pollingEvery(
Duration.ofMillis(500)
)
.ignoring(
NoSuchElementException.class
);
WebElement username =
wait.until(
driver ->
driver.findElement(
By.id("username")
)
);
username.sendKeys("admin");
} finally {
driver.quit();
}
}
}
72. Practical E-Commerce Wait Example
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(15)
);
WebElement searchBox =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("search")
)
);
searchBox.sendKeys("Laptop");
searchBox.sendKeys(Keys.ENTER);
WebElement product =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".product-card")
)
);
System.out.println(
"Product: " + product.getText()
);
WebElement addToCart =
wait.until(
ExpectedConditions.elementToBeClickable(
By.cssSelector(".add-to-cart")
)
);
addToCart.click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".cart-success")
)
);
73. Practical Registration Form Wait Example
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement firstName =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("firstName")
)
);
WebElement email =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("email")
)
);
WebElement password =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("password")
)
);
firstName.sendKeys("John");
email.sendKeys("[email protected]");
password.sendKeys("Password123");
WebElement terms =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("terms")
)
);
if (!terms.isSelected()) {
terms.click();
}
WebElement register =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("register")
)
);
register.click();
74. Page Object Model with Waits
In a professional Selenium framework, explicit waits are commonly centralized or encapsulated within page classes or reusable utility methods. This keeps synchronization logic consistent across tests.
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class LoginPage {
private WebDriver driver;
private WebDriverWait wait;
private By username =
By.id("username");
private By password =
By.id("password");
private By loginButton =
By.id("login");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
}
public void enterUsername(String value) {
WebElement element =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
username
)
);
element.clear();
element.sendKeys(value);
}
public void enterPassword(String value) {
WebElement element =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
password
)
);
element.clear();
element.sendKeys(value);
}
public void clickLogin() {
WebElement element =
wait.until(
ExpectedConditions.elementToBeClickable(
loginButton
)
);
element.click();
}
}
75. Reusable Wait Utility
A reusable wait utility can reduce duplicate wait code in larger Selenium projects.
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class WaitUtility {
private WebDriver driver;
private WebDriverWait wait;
public WaitUtility(WebDriver driver) {
this.driver = driver;
this.wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
}
public WebElement waitForVisible(By locator) {
return wait.until(
ExpectedConditions.visibilityOfElementLocated(
locator
)
);
}
public WebElement waitForClickable(By locator) {
return wait.until(
ExpectedConditions.elementToBeClickable(
locator
)
);
}
public void waitForInvisible(By locator) {
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
locator
)
);
}
}
76. Common Wait-Related Exceptions
| Exception | Possible Cause | Solution |
| TimeoutException | Condition was not satisfied within the timeout | Check locator, condition, page state, and timeout |
| NoSuchElementException | Element could not be found | Verify locator and synchronization |
| StaleElementReferenceException | DOM changed after the element was located | Locate the element again and use an appropriate stale-element wait |
| ElementNotInteractableException | Element cannot receive the requested interaction | Wait for visibility or interactability |
| ElementClickInterceptedException | Another element blocks the target | Wait for overlays to disappear and use elementToBeClickable() |
77. Common Wait Mistakes
- Using Thread.sleep() everywhere.
- Using very large timeout values without justification.
- Waiting for visibility when the actual requirement is clickability.
- Using presence when the element must be visible.
- Using an incorrect locator.
- Ignoring loading overlays.
- Ignoring iframe context.
- Using stale WebElement references.
- Adding unnecessary waits after every Selenium command.
- Mixing implicit and explicit waits without a clear strategy.
- Using JavaScript to bypass synchronization problems.
- Not identifying the actual application condition that indicates readiness.
78. Best Practices for Selenium Waits
- Prefer condition-based synchronization over fixed delays.
- Use explicit waits for important dynamic application states.
- Choose the expected condition that matches the actual requirement.
- Use visibilityOfElementLocated() when an element must be visible.
- Use elementToBeClickable() when an element must be ready for clicking.
- Use presenceOfElementLocated() when DOM presence is sufficient.
- Use invisibilityOfElementLocated() for loading overlays and temporary elements.
- Use stalenessOf() when an old DOM element must disappear.
- Use FluentWait when custom polling or exception handling is required.
- Keep timeout values reasonable and consistent.
- Use reusable wait utilities in larger frameworks.
- Keep synchronization logic close to page interaction logic or in a dedicated utility layer.
- Avoid unnecessary Thread.sleep() calls.
- Do not use waits as a substitute for fixing an incorrect locator.
- Always understand what application state indicates that the next action is safe.
79. Wait Strategy Decision Flow
Does the Test Need Synchronization?
|
Yes
|
v
Is General Element Lookup Delay Enough?
|
+----+----+
| |
Yes No
| |
v v
Implicit Wait Specific Condition?
|
v
Explicit Wait
|
v
Is Advanced Polling Needed?
|
+----+----+
| |
No Yes
| |
v v
WebDriverWait FluentWait
80. Waits with Locator Strategy
Waits and locators work together. A wait cannot compensate for an incorrect or unstable locator. First select a reliable locator, then apply the appropriate synchronization condition.
By loginButton =
By.cssSelector("button.login");
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement button =
wait.until(
ExpectedConditions.elementToBeClickable(
loginButton
)
);
button.click();
81. Waits with WebElement Operations
WebElement username =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("username")
)
);
username.clear();
username.sendKeys("admin");
WebElement password =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("password")
)
);
password.clear();
password.sendKeys("Password123");
WebElement login =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("login")
)
);
login.click();
82. Waits and Page Load
A page navigation command does not necessarily mean that every application element is ready for interaction. Modern applications may continue making API calls and rendering components after the initial navigation.
Therefore, instead of relying only on page navigation completion, wait for an application-specific condition such as a key element becoming visible, a loading overlay disappearing, or a successful navigation state being reached.
83. Waits and AJAX Applications
AJAX-based applications often update individual portions of a page without performing a full browser navigation. In such applications, explicit waits are particularly useful because the test can wait for the specific result of the asynchronous operation.
driver.findElement(
By.id("loadData")
).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("dataResult")
)
);
84. Waits and Loading Spinners
A common real-world synchronization pattern is to wait for a loading spinner to disappear before interacting with the next element.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".spinner")
)
);
WebElement checkout =
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("checkout")
)
);
checkout.click();
85. Waits and Dynamic Tables
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("table tbody tr")
)
);
List<WebElement> rows =
driver.findElements(
By.cssSelector("table tbody tr")
);
for (WebElement row : rows) {
System.out.println(row.getText());
}
86. Waits and Search Suggestions
WebElement search =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("search")
)
);
search.sendKeys("Selenium");
WebElement suggestion =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".suggestion")
)
);
suggestion.click();
87. Waits and File Upload Controls
For a standard file input, Selenium generally interacts directly with the input using sendKeys(). If the input is dynamically rendered, an explicit wait can be used first.
WebElement fileInput =
wait.until(
ExpectedConditions.presenceOfElementLocated(
By.id("fileUpload")
)
);
fileInput.sendKeys(
"C:\\files\\document.pdf"
);
88. Waits and Alerts
driver.findElement(
By.id("delete")
).click();
Alert alert =
wait.until(
ExpectedConditions.alertIsPresent()
);
System.out.println(
alert.getText()
);
alert.accept();
89. Waits and Windows
When an action opens a new browser window or tab, Selenium can wait until the expected number of windows is available.
driver.findElement(
By.id("openWindow")
).click();
wait.until(
ExpectedConditions.numberOfWindowsToBe(
2
)
);
System.out.println(
"Windows: " + driver.getWindowHandles().size()
);
90. Practical Project: Selenium Wait Practice
Build a Selenium Java automation project that demonstrates implicit, explicit, and fluent wait concepts on a dynamic web application.
Project Requirements
- Launch Chrome browser.
- Open a test application.
- Configure an appropriate synchronization strategy.
- Locate a dynamically loaded username field.
- Wait for the username field to become visible.
- Enter username and password.
- Wait for the login button to become clickable.
- Click the login button.
- Wait for a loading indicator to disappear.
- Wait for a success message.
- Validate the success message.
- Wait for the expected URL.
- Handle a dynamically displayed alert if required.
- Close the browser using driver.quit().
91. Practical Complete Wait Program
import java.time.Duration;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class SeleniumWaitPractice {
public static void main(String[] args) {
WebDriver driver =
new ChromeDriver();
try {
driver.manage().window().maximize();
driver.get(
"https://www.selenium.dev/selenium/web/web-form.html"
);
WebDriverWait wait =
new WebDriverWait(
driver,
Duration.ofSeconds(10)
);
WebElement textBox =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.name("my-text")
)
);
textBox.clear();
textBox.sendKeys(
"Selenium Waits with Java"
);
WebElement submitButton =
wait.until(
ExpectedConditions.elementToBeClickable(
By.cssSelector("button")
)
);
submitButton.click();
WebElement message =
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("message")
)
);
System.out.println(
"Message: " + message.getText()
);
} finally {
driver.quit();
}
}
}
92. Interview Questions on Selenium Waits
Q1. What is a wait in Selenium?
A wait is a synchronization mechanism that allows Selenium to wait for a specified condition or element state before continuing execution.
Q2. What are the main types of waits in Selenium?
The commonly discussed Selenium wait mechanisms are Implicit Wait, Explicit Wait, and Fluent Wait. Fixed delays using Thread.sleep() are also possible in Java, but they are not condition-based synchronization.
Q3. What is Implicit Wait?
Implicit Wait configures WebDriver to wait for a specified amount of time during element lookup when the element is not immediately available.
Q4. What is Explicit Wait?
Explicit Wait waits for a particular condition, such as visibility, clickability, text, URL, title, alert presence, or frame availability.
Q5. What is WebDriverWait?
WebDriverWait is a Selenium Java class used for condition-based waits and is a specialization of FluentWait for WebDriver.
Q6. What is FluentWait?
FluentWait is a configurable wait that allows timeout, polling interval, and ignored exceptions to be specified.
Q7. What is ExpectedConditions?
ExpectedConditions is a Selenium support class containing commonly used predefined conditions for explicit waits.
Q8. What is the difference between presence and visibility?
Presence means the element exists in the DOM. Visibility means the element is present and visible for the relevant condition.
Q9. What is elementToBeClickable()?
It waits until an element is visible and enabled so that it can be clicked.
Q10. Why should Thread.sleep() generally be avoided?
Thread.sleep() always pauses for the full fixed duration and does not check whether the application is ready earlier or remains unready longer.
Q11. What happens when an explicit wait times out?
If the required condition is not satisfied within the configured timeout, a timeout-related failure such as TimeoutException can occur.
Q12. How do you wait for an alert?
Alert alert =
wait.until(
ExpectedConditions.alertIsPresent()
);
Q13. How do you wait for an iframe?
wait.until(
ExpectedConditions.frameToBeAvailableAndSwitchToIt(
By.id("frame")
)
);
Q14. How do you wait for a loading spinner to disappear?
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".spinner")
)
);
Q15. Can you create a custom wait condition?
Yes. Java lambdas can be used with wait.until(), and FluentWait can also be configured for custom polling behavior.
93. Quick Revision
| Concept | Java Example | Purpose |
| Implicit Wait | implicitlyWait() | General element lookup synchronization |
| Explicit Wait | WebDriverWait | Wait for a specific condition |
| Fluent Wait | FluentWait | Custom timeout and polling behavior |
| Until | wait.until() | Wait for a condition |
| Presence | presenceOfElementLocated() | Wait for DOM presence |
| Visibility | visibilityOfElementLocated() | Wait for visibility |
| Clickable | elementToBeClickable() | Wait for click readiness |
| Text | textToBePresentInElementLocated() | Wait for text |
| Title | titleIs() | Wait for exact title |
| URL | urlContains() | Wait for URL state |
| Alert | alertIsPresent() | Wait for alert |
| Invisible | invisibilityOfElementLocated() | Wait for element to disappear |
| Stale | stalenessOf() | Wait for DOM detachment |
| Frame | frameToBeAvailableAndSwitchToIt() | Wait for iframe |
| Polling | pollingEvery() | Configure FluentWait polling |
94. Final Summary
Waits with Java in Selenium are essential for creating reliable and stable browser automation. Modern applications frequently load elements asynchronously, update the DOM dynamically, display loading indicators, open dialogs, and change page content after API responses.
Implicit Wait provides general synchronization for element lookup, while Explicit Wait allows the automation script to wait for a specific condition. WebDriverWait is commonly used for explicit waits, and ExpectedConditions provides reusable conditions such as visibility, presence, clickability, text, title, URL, alert, iframe, invisibility, and staleness. :contentReference[oaicite:16]{index=16}
FluentWait provides additional control over timeout, polling interval, and ignored exceptions and is useful when advanced synchronization behavior is required. :contentReference[oaicite:17]{index=17}
For professional Selenium automation, use condition-based synchronization rather than unnecessary fixed delays, select the condition that matches the actual application state, use reliable locators, handle dynamic DOM changes, and centralize reusable wait logic where appropriate.
95. Course Resources
Learn more about Selenium Automation Testing:
Selenium Training
Register for a course demo:
Register for Course Demo